import React, { useEffect, useContext, useState, useRef } from 'react';
import type { ConnectState } from '@/models/connect';
import { connect } from 'umi';
import {
  Card,
  Row,
  Col,
  Tag,
  Form,
  Modal,
  Table,
  Button,
  Select,
  Divider,
  Skeleton,
  Typography,
  InputNumber,
  notification,
} from 'antd';
import { FormInstance } from 'antd/lib/form';
import { CurrentUser } from '../../../models/user';
import { PageContainer } from '@ant-design/pro-layout';
import { teacherInfo, quotaInfo, saveTeachingEvaluationResult } from '@/services/service';

const { Option } = Select;
const { Title, Text } = Typography;
const EditableContext = React.createContext<FormInstance<any> | null>(null);

// [角色]评教的 props 类型
interface IimplementationInterface {
  user: CurrentUser;
}

// 用户角色映射类型
type userRoleMapType = {
  student: string;
  teacher: string;
  supervisor: string;
};

// 教师名称类信息类型
type TeacherInfoNamesType = {
  number: string;
  userName: string;
  academicTitle: string;
};

// 教师课程类信息类型
type TeacherInfoCoursesType = {
  number: string;
  nature: string;
  credit: number;
  period: number;
  courseName: string;
};

// 表格数据项类型
export interface Item {
  key: string;
  firstLevel: string;
  secondLevel: number;
  score: string;
  fraction: number;
}

// 可编辑行的 props 类型
interface EditableRowProps {
  index: number;
}

// 表格列类型
type columnType = {
  children: any;
  props: {
    rowSpan?: number;
    colSpan?: number;
  };
};

// 表格列合并映射规则类型
type columnRowSpanMapType = {
  val: number;
  expression: number[];
};

// 可编辑行
const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => {
  const [form] = Form.useForm();
  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  );
};

// 可编辑单元格类型
interface EditableCellProps {
  title: React.ReactNode;
  editable: boolean;
  children: React.ReactNode;
  dataIndex: keyof Item;
  record: Item;
  handleSave: (record: Item) => void;
}

// 可编辑单元格
const EditableCell: React.FC<EditableCellProps> = ({
  title,
  editable,
  children,
  dataIndex,
  record,
  handleSave,
  ...restProps
}) => {
  const [editing, setEditing] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const form = useContext(EditableContext)!;
  useEffect(() => {
    if (editing) {
      inputRef.current!.focus();
    }
  }, [editing]);

  const toggleEdit = () => {
    setEditing(!editing);
    form.setFieldsValue({
      [dataIndex]: record[dataIndex],
    });
  };

  const save = async () => {
    try {
      const values = await form.validateFields();
      toggleEdit();
      handleSave({ ...record, ...values });
    } catch (errInfo) {
      console.log('Save failed:', errInfo);
    }
  };

  let childNode = children;

  if (editable) {
    childNode = editing ? (
      <Form.Item
        style={{
          margin: 0,
        }}
        name={dataIndex}
        rules={[
          {
            required: true,
            message: `${title} is required.`,
          },
        ]}
      >
        <InputNumber
          min={0}
          max={(() => {
            const result = +record.score;
            return Object.is(NaN, result) ? 0 : result;
          })()}
          ref={inputRef}
          onPressEnter={save}
          onBlur={save}
        />
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        style={{
          paddingRight: 24,
        }}
        onClick={toggleEdit}
      >
        {children}
      </div>
    );
  }

  return <td {...restProps}>{childNode}</td>;
};

// 表格列合并映射规则
const columnRowSpanMap: columnRowSpanMapType[] = [
  {
    val: 4,
    expression: [0],
  },
  {
    val: 0,
    expression: [0, 4],
  },
  {
    val: 4,
    expression: [4],
  },
  {
    val: 0,
    expression: [4, 8],
  },
  {
    val: 3,
    expression: [8],
  },
  {
    val: 0,
    expression: [8, 11],
  },
  {
    val: 3,
    expression: [11],
  },
  {
    val: 0,
    expression: [11, 14],
  },
];

// 表格列
const columns = [
  {
    title: '一级指标',
    dataIndex: 'firstLevel',
    width: 750 / 4,
    render: (text: any, row: Item, index: number) => {
      const obj: columnType = {
        children: text,
        props: {},
      };
      columnRowSpanMap.forEach((item) => {
        const len = item.expression.length;
        if (len === 1) {
          if (index === item.expression[0]) {
            obj.props.rowSpan = item.val;
          }
        }
        if (len !== 1 && index > item.expression[0] && index < item.expression[1]) {
          obj.props.rowSpan = item.val;
        }
      });
      return obj;
    },
  },
  {
    title: '二级指标',
    dataIndex: 'secondLevel',
    width: 750 / 4,
  },
  {
    title: '分数',
    dataIndex: 'score',
    width: 750 / 4,
  },
  {
    title: '得分',
    dataIndex: 'fraction',
    width: 750 / 4,
    editable: true,
  },
];

// [角色]评教
const Implementation: React.FC<IimplementationInterface> = (props) => {
  const [semester, setSemester] = useState('');
  const [semesters, setSemesters] = useState([]);
  const [schoolYear, setSchoolYear] = useState('');
  const [schoolYears, setSchoolYears] = useState([]);
  const [readyState, setReadyState] = useState(false);
  const [modalVisible, setModalVisible] = useState(false);
  const [dataSource, setDataSource] = useState<Item[]>([]);
  const [teacher, setTeacher] = useState<TeacherInfoNamesType | null>(null);
  const [course, setCourse] = useState<TeacherInfoCoursesType | null>(null);
  const [teachers, setTeachers] = useState<TeacherInfoNamesType[]>([]);
  const [courses, setCourses] = useState<TeacherInfoCoursesType[]>([]);

  /* 变量定义区域 start */
  const semesterMap = {
    '1': '一',
    '2': '二',
    '3': '三',
    '4': '四',
    '5': '五',
  };
  /* 变量定义区域 end */

  useEffect(() => {
    (async () => {
      try {
        const result: any = await teacherInfo();
        setReadyState(true);
        setTeachers(result?.info?.names);
        setCourses(result?.info?.courses);
        setSemesters(result?.info?.semesters);
        setSchoolYears(result?.info?.schoolYears);
        try {
          const quotaResult: any = await quotaInfo();
          setDataSource(quotaResult.data);
        } catch (e) {
          console.log(e);
          setReadyState(false);
        }
      } catch (e) {
        console.log(e);
        setReadyState(false);
      }
    })();
  }, []);

  const { user } = props;

  const handleSave = (row: Item) => {
    const newData: any = [...dataSource];
    const index = newData.findIndex((item: Item) => row.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, { ...item, ...row });
    setDataSource(newData);
  };

  const formatSemester = (param: number) => {
    const keys = Object.keys(semesterMap);
    const temp = keys.filter((item) => Number(item) === param);
    return `第${semesterMap[temp[0]]}学期`;
  };

  const userRoleMap: userRoleMapType = {
    student: '学生',
    teacher: '教师',
    supervisor: '督导',
  };

  const getTitle = (roles: userRoleMapType): string => {
    const authority = user.currentAuthority;
    const role = authority ? roles[authority] : '';
    return authority === 'teacher' ? `同行互评` : `${role}评教`;
  };

  const components = {
    body: {
      row: EditableRow,
      cell: EditableCell,
    },
  };
  const realColumns = columns.map((col) => {
    if (!col.editable) {
      return col;
    }

    return {
      ...col,
      onCell: (record: Item) => ({
        record,
        editable: col.editable,
        dataIndex: col.dataIndex,
        title: col.title,
        handleSave,
      }),
    };
  });

  return (
    <div>
      <PageContainer waterMarkProps={{ content: '河北交通职业技术学院' }}>
        <Card style={{ minHeight: 340 }}>
          <Skeleton loading={!readyState} avatar active>
            <Title style={{ textAlign: 'center' }}>{getTitle(userRoleMap)}</Title>
            <Row>
              <Divider orientation="left">教师信息</Divider>
              <Col span={4}>
                <Select
                  placeholder="教师姓名"
                  style={{ width: '100%' }}
                  onChange={(value) => {
                    if (teachers) {
                      setTeacher(teachers.filter((item) => item.userName === value)[0]);
                    }
                  }}
                  allowClear={true}
                >
                  {teachers.map((item, index) => (
                    <Option key={index} value={item.userName}>
                      {item.userName}
                    </Option>
                  ))}
                </Select>
              </Col>
              <Col span={4} offset={2} style={{ display: 'flex', alignItems: 'center' }}>
                {teacher && <Tag>教师编号: {teacher.number}</Tag>}
              </Col>
              <Col span={4} style={{ display: 'flex', alignItems: 'center' }}>
                {teacher && <Tag>职称: {teacher.academicTitle}</Tag>}
              </Col>
            </Row>
            <Row>
              <Divider orientation="left">学年信息</Divider>
              <Col span={4}>
                <Select
                  placeholder="学年"
                  style={{ width: '100%' }}
                  onChange={(value) => {
                    if (value) {
                      setSchoolYear(`${value}`);
                    }
                  }}
                  allowClear={true}
                >
                  {(() => {
                    const result = [];
                    for (let i = 0; i < schoolYears.length - 1; ) {
                      result.push(`${schoolYears[i]}-${schoolYears[i + 1]}`);
                      i += 1;
                    }
                    return result;
                  })().map((item, index) => (
                    <Option key={index} value={item}>
                      {item}
                    </Option>
                  ))}
                </Select>
              </Col>
              <Col span={4} offset={2}>
                <Select
                  placeholder="学期"
                  style={{ width: '100%' }}
                  onChange={(value) => {
                    if (value) setSemester(`${value}`);
                  }}
                  allowClear={true}
                >
                  {semesters.map((item, index) => (
                    <Option key={index} value={formatSemester(item)}>
                      {formatSemester(item)}
                    </Option>
                  ))}
                </Select>
              </Col>
            </Row>
            <Row>
              <Divider orientation="left">课程信息</Divider>
              <Col span={4}>
                <Select
                  placeholder="课程名程"
                  style={{ width: '100%' }}
                  onChange={(value) => {
                    setCourse(courses.filter((item) => item.courseName === value)[0]);
                  }}
                  allowClear={true}
                >
                  {courses.map((item, index) => (
                    <Option key={index} value={item.courseName}>
                      {item.courseName}
                    </Option>
                  ))}
                </Select>
              </Col>
              <Col span={4} offset={2} style={{ display: 'flex', alignItems: 'center' }}>
                {course && <Tag>课程代码: {course.number}</Tag>}
              </Col>
              <Col span={4} offset={1} style={{ display: 'flex', alignItems: 'center' }}>
                {course && <Tag>课程性质: {course.nature}</Tag>}
              </Col>
              <Col span={4} offset={1} style={{ display: 'flex', alignItems: 'center' }}>
                {course && <Tag>学分：{course.credit}</Tag>}
              </Col>
              <Col span={4} style={{ display: 'flex', alignItems: 'center' }}>
                {course && <Tag>课时：{course.period}</Tag>}
              </Col>
            </Row>
            <Row style={{ marginTop: '25px' }}>
              <Col>
                <Button
                  type="primary"
                  onClick={() => {
                    if (
                      teacher &&
                      course &&
                      Object.keys(teacher).length > 0 &&
                      Object.keys(course).length > 0 &&
                      schoolYear &&
                      semester
                    ) {
                      setModalVisible(true);
                    } else {
                      notification.warning({
                        message: '数据未填充完毕',
                        description: '请将所有的表单填写完整',
                      });
                    }
                  }}
                >
                  开始评价
                </Button>
              </Col>
            </Row>
          </Skeleton>
        </Card>
        <Modal
          title={getTitle(userRoleMap)}
          width={750}
          visible={modalVisible}
          destroyOnClose={true}
          onOk={async () => {
            const result: any = await saveTeachingEvaluationResult({
              user: {
                name: user.name,
                department: user.department,
                userNumber: user.number,
                role: user.currentAuthority,
              },
              teacher: {
                name: teacher && teacher.userName,
                academicTitle: teacher && teacher.academicTitle,
                course: course && course.courseName,
                credit: course && course.credit,
              },
              data: dataSource,
            });
            if (result.status === 'ok') {
              const $dataSource = [...dataSource];
              setDataSource(
                $dataSource.map((item) => {
                  const $item = item;
                  $item.fraction = 0;
                  return $item;
                }),
              );
              setModalVisible(false);
            } else {
              notification.error({
                message: '数据提交错误',
                description: '数据提交错误，请关注接口是否报错。如果必要请联系管理员 !',
              });
            }
          }}
          onCancel={() => {
            setModalVisible(false);
          }}
        >
          <Row style={{ display: 'flex', alignItems: 'center' }}>
            <Col>
              <Tag>院系: {user.department}</Tag>
            </Col>
            {user.currentAuthority ? (
              <>
                <Col>
                  <Tag>
                    {userRoleMap[user.currentAuthority]}姓名: {user.name}
                  </Tag>
                </Col>
                <Col>
                  <Tag>
                    {userRoleMap[user.currentAuthority]}编号: {user.number}
                  </Tag>
                </Col>
              </>
            ) : null}
          </Row>
          <Row style={{ marginTop: '15px', display: 'flex', alignItems: 'center' }}>
            <Col>{teacher && <Tag>被评教师姓名: {teacher.userName}</Tag>}</Col>
            <Col>{teacher && <Tag>职称: {teacher.academicTitle}</Tag>}</Col>
            <Col>{course && <Tag>课程名程: {course.courseName}</Tag>}</Col>
            <Col>{course && <Tag>学分 {course.credit}</Tag>}</Col>
          </Row>
          <Row style={{ marginTop: '15px' }}>
            <Col>
              <Table
                components={components}
                rowClassName={() => 'editable-row'}
                bordered
                dataSource={dataSource}
                columns={realColumns}
                pagination={false}
                summary={(pageData) => {
                  const scoreResult = pageData.reduce((prev, next) => {
                    let score = +next.score;
                    score = Object.is(NaN, score) ? 0 : score;
                    return prev + score;
                  }, 0);

                  const fractionResult = pageData.reduce((prev, next) => {
                    let fraction = +next.fraction;
                    fraction = Object.is(NaN, fraction) ? 0 : fraction;
                    return prev + fraction;
                  }, 0);

                  return (
                    <>
                      <Table.Summary.Row>
                        <Table.Summary.Cell index={0}></Table.Summary.Cell>
                        <Table.Summary.Cell index={1}>
                          <Text type="danger">总分</Text>
                        </Table.Summary.Cell>
                        <Table.Summary.Cell index={2}>
                          <Text>{scoreResult}</Text>
                        </Table.Summary.Cell>
                        <Table.Summary.Cell index={3}>
                          <Text>{fractionResult}</Text>
                        </Table.Summary.Cell>
                      </Table.Summary.Row>
                    </>
                  );
                }}
              />
            </Col>
          </Row>
        </Modal>
      </PageContainer>
    </div>
  );
};

const mapStateFromProps = ({ user }: ConnectState): IimplementationInterface => ({
  user: user.currentUser as CurrentUser,
});

export default connect(mapStateFromProps)(Implementation);
